#include "GraphData.h"
#include <fstream>
#include <sstream>
#include <iostream>
#include <unordered_map>

GraphData readGraphData(const std::string& nodesFile, const std::string& edgesFile) {
    GraphData graph;

    // 读取 nodes.csv
    std::ifstream nf(nodesFile);
    if (!nf.is_open()) {
        throw std::runtime_error("Failed to open " + nodesFile);
    }

    std::string line;
    std::getline(nf, line);  // 跳过 header
    while (std::getline(nf, line)) {
        std::istringstream ss(line);
        std::string idStr, lonStr, latStr;
        std::getline(ss, idStr, ',');
        std::getline(ss, lonStr, ',');
        std::getline(ss, latStr, ',');

        Node node;
        node.id = std::stoi(idStr);
        node.lon = std::stod(lonStr);
        node.lat = std::stod(latStr);
        graph.nodes.push_back(node);
    }

    nf.close();

    // 读取 edges.csv
    std::ifstream ef(edgesFile);
    if (!ef.is_open()) {
        throw std::runtime_error("Failed to open " + edgesFile);
    }

    std::getline(ef, line); // 读取 header
    std::istringstream hs(line);
    std::vector<std::string> headers;
    std::string col;
    while (std::getline(hs, col, ',')) {
        headers.push_back(col);
    }

    int fromIdx = 0, toIdx = 1;
    bool useHeader = headers.size() > 2;  // 如果有 weight，我们才用 header 做索引

    if (useHeader) {
        fromIdx = -1;
        toIdx = -1;
        for (size_t i = 0; i < headers.size(); ++i) {
            if (headers[i] == "from") fromIdx = i;
            else if (headers[i] == "to") toIdx = i;
        }
        if (fromIdx == -1 || toIdx == -1) {
            throw std::runtime_error("Missing 'from' or 'to' in edges file header.");
        }
    }

    // 逐行读取 edge 内容
    while (std::getline(ef, line)) {
        std::istringstream ss(line);
        std::vector<std::string> fields;
        std::string value;

        while (std::getline(ss, value, ',')) {
            fields.push_back(value);
        }

        if (fields.size() <= std::max(fromIdx, toIdx)) continue;

        Edge edge;
        edge.from = std::stoi(fields[fromIdx]);
        edge.to = std::stoi(fields[toIdx]);
        graph.edges.push_back(edge);
    }
    ef.close();
    return graph;
}
